#include "qtWin_SQ.h"

#include <QtGui>

#include "misc.h"

extern hybroid *Hybroids[MAX_NUM_HYBROIDS];
extern hybroid *h1;
extern int Num_Hybroids, Num_Constraints;

qtWin_SQ::qtWin_SQ()
{
	this->setupUi(this);

	m_loaded_hybroid = false;

	makeConnections();

	//lineEdit_sc->(0);
	//lineEdit_sc->setMaximum(100);
	horizontalSlider_a1->setMinimum(0);
	horizontalSlider_a1->setMaximum(100);
	horizontalSlider_a2->setMinimum(0);
	horizontalSlider_a2->setMaximum(100);
	horizontalSlider_a3->setMinimum(0);
	horizontalSlider_a3->setMaximum(100);
	horizontalSlider_e1->setMinimum(0);
	horizontalSlider_e1->setMaximum(300);
	horizontalSlider_e2->setMinimum(0);
	horizontalSlider_e2->setMaximum(300);
	horizontalSlider_tx->setMinimum(-200);
	horizontalSlider_tx->setMaximum(200);
	horizontalSlider_ty->setMinimum(-200);
	horizontalSlider_ty->setMaximum(200);
	horizontalSlider_b1->setMinimum(-400);
	horizontalSlider_b1->setMaximum(400);
	horizontalSlider_b2->setMinimum(-100);
	horizontalSlider_b2->setMaximum(100);
	horizontalSlider_b3->setMinimum(10);
	horizontalSlider_b3->setMaximum(100);
	m_active_parameter = false;
	m_stop = false;

	// Zhennan: init default file path
	filename = "C:/Users/Mingchen/RESEARCH/deform_model/current/data/hybroid.txt";
	filename2 = "C:/Users/Mingchen/RESEARCH/deform_model/current/data/f0";
}

void qtWin_SQ::makeConnections()
{
	connect(actionOpen, SIGNAL(triggered()), this, SLOT(onActionOpen()));
	connect(pushButton_show, SIGNAL(clicked()), this, SLOT(onBtnShow()));
	connect(pushButton_stop, SIGNAL(clicked()), this, SLOT(onBtnStop()));
	connect(lineEdit_sc, SIGNAL(textEdited (const QString &)), this, SLOT(setValueSC(const QString &)));
	connect(horizontalSlider_a1, SIGNAL(valueChanged(int)), this, SLOT(setValueA1(int)));
	connect(horizontalSlider_a2, SIGNAL(valueChanged(int)), this, SLOT(setValueA2(int)));
	connect(horizontalSlider_a3, SIGNAL(valueChanged(int)), this, SLOT(setValueA3(int)));
	connect(horizontalSlider_e1, SIGNAL(valueChanged(int)), this, SLOT(setValueE1(int)));
	connect(horizontalSlider_e2, SIGNAL(valueChanged(int)), this, SLOT(setValueE2(int)));
	connect(horizontalSlider_tx, SIGNAL(valueChanged(int)), this, SLOT(setValueTx(int)));
	connect(horizontalSlider_ty, SIGNAL(valueChanged(int)), this, SLOT(setValueTy(int)));
	connect(horizontalSlider_b1, SIGNAL(valueChanged(int)), this, SLOT(setValueB1(int)));
	connect(horizontalSlider_b2, SIGNAL(valueChanged(int)), this, SLOT(setValueB2(int)));
	connect(horizontalSlider_b3, SIGNAL(valueChanged(int)), this, SLOT(setValueB3(int)));

	connect(horizontalSlider_a1, SIGNAL(sliderReleased()), this, SLOT(onParaChange()));
	connect(horizontalSlider_a2, SIGNAL(sliderReleased()), this, SLOT(onParaChange()));
	connect(horizontalSlider_a3, SIGNAL(sliderReleased()), this, SLOT(onParaChange()));
	connect(horizontalSlider_e1, SIGNAL(sliderReleased()), this, SLOT(onParaChange()));
	connect(horizontalSlider_e2, SIGNAL(sliderReleased()), this, SLOT(onParaChange()));
	connect(horizontalSlider_tx, SIGNAL(sliderReleased()), this, SLOT(onParaChange()));
	connect(horizontalSlider_ty, SIGNAL(sliderReleased()), this, SLOT(onParaChange()));
	connect(horizontalSlider_b1, SIGNAL(sliderReleased()), this, SLOT(onParaChange()));
	connect(horizontalSlider_b2, SIGNAL(sliderReleased()), this, SLOT(onParaChange()));
	connect(horizontalSlider_b3, SIGNAL(sliderReleased()), this, SLOT(onParaChange()));
}

void qtWin_SQ::onParaChange()
{
	m_active_parameter = true;

	compute_positions(h1);
	compute_superquadric_taper_bend(h1);
	//this->widget_vtkRender->initHybroid(h1, 0, 255, 255);
	this->widget_vtkRender->renderHybroid(h1, 0, 255, 255);
}

void qtWin_SQ::setValueSC(const QString & text)
{
	if(!m_loaded_hybroid)
		return;
	bool ok;
	double v = text.toDouble(&ok);
	if(ok == false){
		lineEdit_sc->setFocus();
		return;
	}
	h1->sc = v;
    h1->sc = Max(h1->sc, 0.0);
	onParaChange();
}
void qtWin_SQ::setValueA1(int v)
{
	if(!m_loaded_hybroid)
		return;
	h1->a1 = 0.01*v;
	//printf(" h1->a1 %f \n", h1->a1);
    h1->a1 = Limit(h1->a1, 0.0, 1.0);
	v_a1->setText(QString::number(h1->a1));
	onParaChange();
}
void qtWin_SQ::setValueA2(int v)
{
	if(!m_loaded_hybroid)
		return;
	h1->a2 = 0.01*v;
    h1->a2 = Limit(h1->a2, 0.0, 1.0);
	v_a2->setText(QString::number(h1->a2));
	onParaChange();
}
void qtWin_SQ::setValueA3(int v)
{
	if(!m_loaded_hybroid)
		return;
	h1->a3 = 0.01*v;
    h1->a3 = Limit(h1->a3, 0.0, 1.0);
	v_a3->setText(QString::number(h1->a3));
	onParaChange();
}
void qtWin_SQ::setValueE1(int v)
{
	if(!m_loaded_hybroid)
		return;
	h1->e1 = 0.01*v;
    h1->e1 = Limit(h1->e1, 0.0, 3.0);
	v_e1->setText(QString::number(h1->e1));
	onParaChange();
}
void qtWin_SQ::setValueE2(int v)
{
	if(!m_loaded_hybroid)
		return;
	h1->e2 = 0.01*v;
    h1->e2 = Limit(h1->e2, 0.0, 3.0);
	v_e2->setText(QString::number(h1->e2));
	onParaChange();
}
void qtWin_SQ::setValueTx(int v)
{
	if(!m_loaded_hybroid)
		return;
	h1->tapx = 0.01*v;
    h1->tapx = Limit(h1->tapx, -2.0, 2.0);
	v_tx->setText(QString::number(h1->tapx));
	onParaChange();
}
void qtWin_SQ::setValueTy(int v)
{
	if(!m_loaded_hybroid)
		return;
	h1->tapy = 0.01*v;
    h1->tapy = Limit(h1->tapy, -2.0, 2.0);
	v_ty->setText(QString::number(h1->tapy));
	onParaChange();
}
void qtWin_SQ::setValueB1(int v)
{
	if(!m_loaded_hybroid)
		return;
	h1->bend1 = 0.01 * v;
    h1->bend1 = Limit(h1->bend1, -4.0, 4.0);
	v_b1->setText(QString::number(h1->bend1));
	onParaChange();
}
void qtWin_SQ::setValueB2(int v)
{
	if(!m_loaded_hybroid)
		return;
	h1->bend2 = 0.01 * v;
	h1->bend2 = Limit(h1->bend2, -1.0, 1.0);
	v_b2->setText(QString::number(h1->bend2));
	onParaChange();
}
void qtWin_SQ::setValueB3(int v)
{
	if(!m_loaded_hybroid)
		return;
	h1->bend3 = 0.01 * v;
    h1->bend3 = Limit(h1->bend3, 0.1, 1.0);
	v_b3->setText(QString::number(h1->bend3));
	onParaChange();
}

void qtWin_SQ::initParameters(hybroid *h)
{
	if(h == NULL)
		return;
	lineEdit_sc->setText(QString::number(h->sc));
	horizontalSlider_a1->setValue(Limit((int)(100 * h->a1 + 0.5), 0, 100));
	v_a1->setText(QString::number(h->a1));
	horizontalSlider_a2->setValue(Limit((int)(100 * h->a2 + 0.5), 0, 100));
	v_a2->setText(QString::number(h->a2));
	horizontalSlider_a3->setValue(Limit((int)(100 * h->a3 + 0.5), 0, 100));
	v_a3->setText(QString::number(h->a3));
	horizontalSlider_e1->setValue(Limit((int)(100 * h->e1 + 0.5), 0, 300));
	v_e1->setText(QString::number(h->e1));
	horizontalSlider_e2->setValue(Limit((int)(100 * h->e2 + 0.5), 0, 300));
	v_e2->setText(QString::number(h->e2));
	horizontalSlider_tx->setValue(Limit((int)(100 * h->tapx + 0.5), -200, 200));
	v_tx->setText(QString::number(h->tapx));
	horizontalSlider_ty->setValue(Limit((int)(100 * h->tapy + 0.5), -200, 200));
	v_ty->setText(QString::number(h->tapy));
	horizontalSlider_b1->setValue(Limit((int)(100 * h->bend1 + 0.5), -400, 400));
	v_b1->setText(QString::number(h->bend1));
	horizontalSlider_b2->setValue(Limit((int)(100 * h->bend2 + 0.5), -100, 100));
	v_b2->setText(QString::number(h->bend2));
	horizontalSlider_b3->setValue(Limit((int)(100 * h->bend3 + 0.5), 10, 100));
	v_b3->setText(QString::number(h->bend3));
}

void qtWin_SQ::onActionOpen()
{
	qtOpen_Wizard openWizard(this);
	openWizard.lineEdit_filepath->setText(QString(filename));	// zhennan: init default filepath
	openWizard.lineEdit_filepath2->setText(QString(filename2));	// zhennan: init default filepath
	openWizard.move(this->pos().x()+(this->width()-openWizard.width())/2, this->pos().y()+(this->height()-openWizard.height())/2);
	int ret = openWizard.exec();
	//QString filename, filename2;

	/*if( openWizard.lineEdit_filepath->text().isEmpty() ||  openWizard.lineEdit_filepath2->text().isEmpty() ){
		filename = "C:/Users/Mingchen/RESEARCH/deform_model/current/data/hybroid.txt";
		filename2 = "C:/Users/Mingchen/RESEARCH/deform_model/current/data/f0";
	}
	else{*/
		filename = openWizard.lineEdit_filepath->text().toStdString().c_str();
		filename2 = openWizard.lineEdit_filepath2->text().toStdString().c_str();
	//}

	switch (ret) {
		case 1:	// finish
			/* Hybroid Initialization */
			
			//read_Hybroids(openWizard.lineEdit_filepath->text().toStdString().c_str());
			read_Hybroids(filename.toStdString().c_str());

			h1 = Hybroids[0];
			Hybroids[0]->translation.x = 0.0;
  
			m_initial_axis.x = 0.0; m_initial_axis.y = 1.0; m_initial_axis.z = 0.0;
			unit_quaternion(0.0, m_initial_axis, Hybroids[0]->orientation);
			unit_quaternion_to_rotation_matrix(Hybroids[0]->orientation, 
												Hybroids[0]->rotation);

			initParameters(h1);
 
			//read_ascii_xyz_data_hybroids(openWizard.lineEdit_filepath2->text().toStdString().c_str(), Hybroids, Num_Hybroids, 105.0); 
			read_ascii_xyz_data_hybroids(filename2.toStdString().c_str(), Hybroids, Num_Hybroids, 105.0); 


			m_loaded_hybroid = true;

			// init UI
			this->widget_vtkRender->initRangeData(h1, 255, 0, 0);
			this->widget_vtkRender->renderRangeData(h1, 255, 0, 0);
			compute_positions(h1);
			this->widget_vtkRender->initHybroid(h1, 0, 255, 255);
			this->widget_vtkRender->initForce(h1, 0, 255, 0);
			
			//printh(h1);
			this->widget_vtkRender->renderHybroid(h1, 0, 255, 255);
			this->widget_vtkRender->renderForces(h1, 0, 255, 0);

			//zeroize_force(h1);

			break;
		case 0: // cancel or close
			// nothing
			break;
		default:
			break;
	}
	
}

void qtWin_SQ::onBtnStop()
{
	m_stop = true;
}

void qtWin_SQ::onBtnShow()
{
	//int count = 0;
	int i;
	hybroid *h;
	char base_name[256], dump_filename[256], junk[256];
	int frame_n =0, Window;

	strcpy(base_name,"file");
	//m_stop = false;

	//h = Hybroids[0];
	//this->widget_vtkRender->renderHybroid(h, 0, 255, 255);


	//while(!m_stop)
	for (int loops = 0; loops<100; loops ++)
	{
		// change parameters
		//user();
		//if(m_active_parameter){
		//
		//	compute_superquadric(h1);
		//
		//	compute_superquadric_taper_bend(h1);

		//	m_active_parameter = false;
		//}

		for(i = 0; i < Num_Hybroids; i++)
			zeroize_force(Hybroids[i]);

		//if (count == 360)
		//	count=0;
		//count++;

		//RGBcolor(0, 0, 30);
		//clear();

		//RGBcolor(255, 255, 255);

		for(i = 0; i < Num_Hybroids; i++) {
			h = Hybroids[i];

			if(i != 2)
			compute_range_data_forces_exhaustive(h);
		}

		for(i = 0; i < Num_Hybroids; i++) {
			if(i != 2)
			compute_motion(Hybroids[i]);
			h = Hybroids[i];
			if(i == 2){
				 compute_positions(h);
				 unrotate_force(h);

				 compute_rigid_motion(h);
				 compute_superquadric_deformation_taper_bend(h);

			}

			// TODO:
		// draw triangular mesh
			this->widget_vtkRender->renderHybroid(h, 0, 255, 255);
			this->widget_vtkRender->renderForces(h, 0, 255, 0);
		 //   RGBcolor(0, 255, 255);
		 //   draw_triangular_mesh(h, posit);
       
	/*
			draw_elements_flat_shading(h);
	*/
		}

		//RGBcolor(255, 0, 0);
	/* SOS need to change this function not to display the relevant data i =2 */   
		// TODO:
		//display_range_data_hybroids(Hybroids, Num_Hybroids);


		//swapbuffers();
		/* routine to store the program output */
		if (0){ //(getbutton(F2KEY)==1) {
			// TODO: set Window as the handler of current 3D window
			sprintf(dump_filename, "%s-%d.rgb", base_name, frame_n);
			dump_window(Window, dump_filename);
			printf("DUMP_WINDOW: Enter filename: ");
			scanf("%s", junk);
			frame_n++;
		}
	}
}

/*
Class Start_Wizard
*/
qtOpen_Wizard::qtOpen_Wizard(QWidget *parent)
	: QWizard(parent)
{
	this->setupUi(this);

	makeConnections();
}

void qtOpen_Wizard::makeConnections()
{
	connect(pushButton_open, SIGNAL(clicked()), this, SLOT(OnOpenBtn()));
	connect(pushButton_open2, SIGNAL(clicked()), this, SLOT(OnOpenBtn2()));
}

void qtOpen_Wizard::OnOpenBtn()
{
	QString filename = QFileDialog::getOpenFileName(this,
                          tr("Open hybroid Config File"), QDir::currentPath(), tr("Config Files (*)"));

	if (!filename.isEmpty()) {
		lineEdit_filepath->setText(filename);
	}
}

void qtOpen_Wizard::OnOpenBtn2()
{
	QString filename = QFileDialog::getOpenFileName(this,
                          tr("Open hybroid XYZ Data File"), QDir::currentPath(), tr("Data Files (*)"));

	if (!filename.isEmpty()) {
		lineEdit_filepath2->setText(filename);
	}
}

bool qtOpen_Wizard::validateCurrentPage ()
{
	QFile file, file2;

	switch(currentId()){
		case 0:
			QString filename;
			QString filename2;

			if( lineEdit_filepath->text().isEmpty()){
				filename = "C:/Users/Mingchen/RESEARCH/deform_model/current/data/hybroid.txt";
			}
			else
				filename = lineEdit_filepath->text();

			if(lineEdit_filepath2->text().isEmpty() ){
				filename2 = "C:/Users/Mingchen/RESEARCH/deform_model/current/data/f0";
			}
			else
				filename2 = lineEdit_filepath2->text();


			printf("Reading hybroid model file: %s\n", filename.toStdString().c_str());
			printf("Reading object file: %s\n", filename2.toStdString().c_str());

			QFile file(filename);
			QFile file2(filename2);

							
				int opened = 0;
				if (file.open(QIODevice::ReadOnly)) {
					QString line;
					QTextStream in(&file);
					while (!in.atEnd()) {
						line = in.readLine();
						if (line.contains("SuperQuadric")) {
							file.close();
							opened++;
							break;
						}
					}
					if(opened == 0){
						file.close();
						return false;
					}
				}
				if (file2.open(QIODevice::ReadOnly)) {
					opened++;
					file2.close();
				}

				if(opened == 2){
					return true;
				}
				return false;
			//}

		//default:
		//	return true;
	}
	return true;
}